// Copyright 2010 The Go Example Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.


package main

import (
	"fmt"
	"json"
	"os"
	"reflect"
	"strings"
)

//define a person info type
type person struct {
	name string
	age  int
	sex  string
}

func (p *person) String() string {
	var content string
	content = "Name:\t" + p.name
	content += "\nAge: \t" + fmt.Sprint(p.age)
	content += "\nSex:\t" + p.sex
	return content
}


func main() {
	//define filename
	var fileName string = "data/person.json"
	//Open File 
	//打开文件
	fn, err := os.Open(fileName, os.O_RDONLY, 0444)

	if err != nil {
		// when can't open file ,the program exit
		//打开文件失败时退出
		fmt.Print("can't open file")
		os.Exit(1)
	}

	//Close File 
	//关闭文件
	defer fn.Close()

	p1 := &person{"Jack", 22, "man"}

	fmt.Print("Person 1 :\n")
	fmt.Println(p1)

	var p2 *person = new(person)

	p2.name = "魏仁言"
	p2.age = 24
	p2.sex = "男"

	fmt.Print("Person 2 :\n")
	fmt.Println(p2)

	var p3 *person = &person{"Bill", 25, "man"}

	fmt.Print("Person 3 :\n")
	fmt.Println(p3)

	//read1(fn)	

	//read2(fn)

	read3(fn)
}

//记取JSON文件
func read1(fn *os.File) {
	//Create Json Decoder
	//创建Json 解码器
	ml := json.NewDecoder(fn)

	for {
		//Go解析Json记录类型对应关系
		//Go Type			JSON Type
		//bool				booleans
		//float64			numbers
		//string			strings
		//[]interface{}			arrays
		//map[string]interface{}	objects
		//nil				null

		var p map[string]interface{}

		err := ml.Decode(&p)

		if err != nil {
			break
		}

		fmt.Println(p)
		//print p["age"] 值类型
		age := p["age"]
		t := reflect.Typeof(age)

		fmt.Println(t)

		f := age.(float64)
		fmt.Println(int(f))

		p1 := getPerson(p)
		fmt.Println(p1)

	}
}

//记取JSON文件 
//只解析一条记录的JSON文件
func read2(fn *os.File) {
	var content string = ""

	var t map[string]interface{}
	//var t []interface{}

	for {
		var buff [256]byte
		i, e := fn.Read(buff[:])
		//i,e :=io.ReadFull(fn,buff[:])
		fmt.Println(i)
		if e != nil {
			break
		}
		if i == 0 {
			break
		}

		content = content + string(buff[0:i])

		//只能解析一条JSON记录
		json.Unmarshal(buff[0:i], &t)

		fmt.Println(t)
	}

	fmt.Println(t)
	fmt.Print(content)
	p := getPerson(t)

	fmt.Println(p)
}

//记取JSON文件 
//可以解析多条记录的JSON文件
func read3(fn *os.File) {
	var content string = ""

	var t map[string]interface{}
	//var t []interface{}

	for {
		var buff [256]byte
		i, e := fn.Read(buff[:])
		//i,e :=io.ReadFull(fn,buff[:])
		fmt.Println(i)
		if e == nil {

		}
		if i == 0 {
			break
		}

		content = content + string(buff[0:i])

	}

	fmt.Print("JSON Record:\n")
	fmt.Print(content)

	fmt.Print("Person Record:\n")

	person := strings.Split(content, "\n", -1)

	//解析每一条JSON记录
	for i := 0; i < len(person); i += 1 {
		//
		bp := []byte(person[i])

		//只能解析一条JSON记录
		json.Unmarshal(bp[:], &t)
		fmt.Println(t)

		p := getPerson(t)
		//打印Person 信息
		fmt.Println(p)
	}

}

//将读取的Json 记录转换成 person 类型
//通过反射将interface{}转换成需要的类型
func getPerson(t map[string]interface{}) (p *person) {
	//covert interface type to string or float64 type
	name := t["name"].(string)
	age := t["age"].(float64)
	sex := t["sex"].(string)

	p = &person{name, int(age), sex}

	return p
}
